/**
 * JWT工具模块
 * 提供JWT令牌的生成和验证功能
 */

const jwt = require('jsonwebtoken');
const { logError } = require('../logger');

// 从环境变量获取JWT密钥
const JWT_SECRET = process.env.JWT_SECRET;
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '24h';
const REFRESH_TOKEN_SECRET = process.env.REFRESH_TOKEN_SECRET || process.env.JWT_SECRET;
const REFRESH_TOKEN_EXPIRES_IN = process.env.REFRESH_TOKEN_EXPIRES_IN || '7d';

// 验证必要的环境变量是否存在
if (!JWT_SECRET) {
  throw new Error('JWT_SECRET环境变量未设置，服务无法启动');
}

/**
 * 生成JWT令牌
 * @param {Object} payload - 要包含在令牌中的数据
 * @returns {string} JWT令牌
 */
function generateToken(payload) {
  try {
    // 确保payload不包含敏感信息
    const safePayload = { ...payload };
    delete safePayload.password;
    delete safePayload.credentials;
    
    return jwt.sign(safePayload, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });
  } catch (error) {
    // 避免记录敏感信息到日志
    logError('生成JWT令牌失败');
    throw new Error('令牌生成失败');
  }
}

/**
 * 验证JWT令牌
 * @param {string} token - 要验证的JWT令牌
 * @returns {Object|null} 解码后的令牌数据，如果验证失败则返回null
 */
function verifyToken(token) {
  if (!token) {
    logError('JWT令牌验证失败: 令牌为空');
    return null;
  }
  
  try {
    return jwt.verify(token, JWT_SECRET);
  } catch (error) {
    // 根据错误类型记录适当的日志
    let errorType = 'unknown';
    if (error.name === 'TokenExpiredError') {
      errorType = 'expired';
    } else if (error.name === 'JsonWebTokenError') {
      errorType = 'invalid';
    }
    
    logError(`JWT令牌验证失败: ${errorType}`);
    return null;
  }
}

/**
 * 解码JWT令牌（不验证）
 * @param {string} token - 要解码的JWT令牌
 * @returns {Object|null} 解码后的令牌数据，如果解码失败则返回null
 */
function decodeToken(token) {
  try {
    return jwt.decode(token);
  } catch (error) {
    logError('解码JWT令牌失败', { error: error.message });
    return null;
  }
}

/**
 * 生成刷新令牌
 * @param {Object} payload - 要包含在刷新令牌中的数据
 * @returns {string} 刷新令牌
 */
function generateRefreshToken(payload) {
  try {
    // 刷新令牌只包含必要的用户标识信息
    const refreshPayload = {
      id: payload.id,
      username: payload.username
    };
    
    return jwt.sign(refreshPayload, REFRESH_TOKEN_SECRET, { expiresIn: REFRESH_TOKEN_EXPIRES_IN });
  } catch (error) {
    // 避免记录敏感信息到日志
    logError('生成刷新令牌失败');
    throw new Error('刷新令牌生成失败');
  }
}

/**
 * 验证刷新令牌
 * @param {string} token - 要验证的刷新令牌
 * @returns {Object|null} 解码后的令牌数据，如果验证失败则返回null
 */
function verifyRefreshToken(token) {
  if (!token) {
    logError('刷新令牌验证失败: 令牌为空');
    return null;
  }
  
  try {
    return jwt.verify(token, REFRESH_TOKEN_SECRET);
  } catch (error) {
    // 根据错误类型记录适当的日志
    let errorType = 'unknown';
    if (error.name === 'TokenExpiredError') {
      errorType = 'expired';
    } else if (error.name === 'JsonWebTokenError') {
      errorType = 'invalid';
    }
    
    logError(`刷新令牌验证失败: ${errorType}`);
    return null;
  }
}

module.exports = {
  generateToken,
  verifyToken,
  decodeToken,
  generateRefreshToken,
  verifyRefreshToken
};